﻿using System;
using System.Collections.Generic;
using System.Xml;

namespace WeixinSDK.Message
{
    /// <summary>
    /// 微信消息,用于接受和回复
    /// </summary>
    public class WxMsg : Dictionary<string, string>
    {
        /// <summary>
        /// 发送方帐号（一个OpenID）
        /// </summary>
        public string FromUserName
        {
            get { return this[WxMsgField.FromUserName]; }
            set { this[WxMsgField.FromUserName] = value; }
        }

        /// <summary>
        /// 接收方账号
        /// </summary>
        public string ToUserName
        {
            get { return this[WxMsgField.ToUserName]; }
            set { this[WxMsgField.ToUserName] = value; }
        }

        /// <summary>
        /// 消息类型
        /// </summary>
        public WxMsgType MsgType
        {
            get
            {
                WxMsgType msgType;
                return Enum.TryParse<WxMsgType>(this[WxMsgField.MsgType], out msgType) ? msgType : WxMsgType.none;
            }
            set
            {
                this[WxMsgField.MsgType] = value.ToString();
            }
        }

        /// <summary>
        /// [接受]消息id，64位整型，数据不存在或解析失败，返回-1
        /// </summary>
        public long MsgId
        {
            get
            {
                var strId = this[WxMsgField.MsgId];
                if (string.IsNullOrEmpty(strId)) return -1;
                long num;
                return Int64.TryParse(strId, out num) ? num : -1;
            }
        }

        /// <summary>
        /// 消息创建时间
        /// </summary>
        public DateTime CreateTime
        {
            get
            {
                var timeStamp = this[WxMsgField.CreateTime];
                if (string.IsNullOrWhiteSpace(timeStamp)) return DateTime.MinValue;
                long lTime;
                if (long.TryParse(timeStamp + "0000000", out lTime))
                {
                    DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
                    TimeSpan toNow = new TimeSpan(lTime);
                    return dtStart.Add(toNow);
                }
                return DateTime.MinValue;
            }
        }

        public new string this[string key]
        {
            get
            {
                string value;
                return TryGetValue(key, out value) ? value : null;
            }
            set
            {
                base[key] = value;
            }
        }

        public string this[WxMsgField field]
        {
            get
            {
                return this[field.ToString()];
            }
            set
            {
                base[field.ToString()] = value;
            }
        }

        /// <summary>
        /// 解析收到的消息
        /// </summary>
        /// <param name="msgXml"></param>
        /// <returns></returns>
        public static WxMsg ParseReceivedMessage(string msgXml)
        {
            string key = null;
            var msg = new WxMsg();

            using (System.IO.TextReader tr = new System.IO.StringReader(msgXml))
            {
                XmlReader xr = new XmlTextReader(tr);

                while (xr.Read())
                {
                    if (xr.Depth < 1) continue;

                    if (xr.NodeType == XmlNodeType.Element)
                    {
                        key = xr.Name;
                    }
                    else if (xr.NodeType == XmlNodeType.CDATA)
                    {
                        msg[key] = xr.Value;
                    }
                }
            }

            return msg;
        }
    }
}
